643,BFS解腐烂的橘子问题
问题描述
来源:LeetCode第994题
难度:中等
在给定的mxn网格grid中,每个单元格可以有以下三个值之一:
值 0 代表空单元格;
值 1 代表新鲜橘子;
值 2 代表腐烂的橘子。
每分钟,腐烂的橘子周围4个方向上相邻的新鲜橘子都会腐烂。返回直到单元格中没有新鲜橘子为止所必须经过的最小分钟数。如果不可能,返回-1。
示例 1:
输入:grid = [[2,1,1],[1,1,0],[0,1,1]]
输出:4
示例 2:
输入:grid = [[2,1,1],[0,1,1],[1,0,1]]
输出:-1
解释:左下角的橘子(第 2 行, 第 0 列)永远不会腐烂,因为腐烂只会发生在 4 个正向上。
示例 3:
输入:grid = [[0,2]]
输出:0
解释:因为 0 分钟时已经没有新鲜橘子了,所以答案就是 0 。
提示:
m == grid.length
n == grid[i].length
1 <= m, n <= 10
grid[i][j] 仅为 0、1 或 2
BFS解决
题中说的是每个腐烂橘子的上下左右四个方向的新鲜橘子1分钟之后都会腐烂,一种解决思路就是先找出所有腐烂的橘子把他们放到一个队列中,下一步遍历队列中所有腐烂的橘子,往他们的上下左右四个方向查找,如果有新鲜的橘子,就让他们腐烂,然后把他们在加入到队列中……直到队列为空为止。我们以示例一为例来看一下
我们来看下代码
public int orangesRotting(int[][] grid) {
int m = grid.length;//网格高度
int n = grid[0].length;//网格宽度
//放腐烂橘子的坐标
Queue<int[]> queue = new LinkedList<>();
int fresh = 0;//新鲜橘子的数量
//找出腐烂的橘子
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (grid[i][j] == 2) {
//把腐烂的橘子加入到队列中
queue.offer(new int[]{i, j});
} else if (grid[i][j] == 1) {
//新鲜的橘子
fresh++;
}
}
}
//如果没有腐烂的橘子,直接返回0
if (fresh == 0)
return 0;
//计算时间
int times = -1;
//方向数组
int[][] dirs = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
while (!queue.isEmpty()) {
//当前队列中腐烂橘子的数量
int size = queue.size();
times++;//需要的时间
while (size-- > 0) {
int[] poll = queue.poll();//腐烂的橘子
//遍历当前腐烂橘子的上下左右四个方向
for (int[] dir : dirs) {
int x = poll[0] + dir[0];
int y = poll[1] + dir[1];
if (x >= 0 && x < m && y >= 0 && y < n && grid[x][y] == 1) {
fresh--;//新鲜橘子数量减1
grid[x][y] = 2;//让他腐烂
queue.offer(new int[]{x, y});//腐烂之后加入到队列中
}
}
}
}
return fresh == 0 ? times : -1;
}
截止到目前我已经写了600多道算法题了,为了方便大家阅读,我把部分算法题整理成了pdf文档,目前有1000多页,大家可以在下面公众号“数据结构和算法”中回复关键字“pdf”即可获取下载链接。
想学习算法,还可以长按下面二维码加我微信,我给你拉到算法学习群,在工作中或者学习中遇到不会的问题都可以在群里讨论。